# -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2016  德清武康开源软件().
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from odoo import api, fields, models, tools, _
from odoo.exceptions import UserError
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as dt
import time
from datetime import datetime, timedelta

class HouseType(models.Model):
    _name = "house.type"
    _description = "House Type"

    name = fields.Char(required=True)
    is_room = fields.Boolean(string='是房间', default=True)

class HouseRoom(models.Model):
    _name = 'house.room'
    _description = 'Private House Room'
    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']

    name = fields.Char('房间号', required=True, delegate=True, ondelete='cascade')
    max_adult = fields.Integer()
    max_child = fields.Integer()
    categ_id = fields.Many2one('house.type', string='房型', domain=[('is_room', '=', True)],
                               required=True)
    room_amount = fields.Float('房间价格')

class HouseOrder(models.Model):
    _name = 'house.order'
    _description = 'Private House Order'
    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
    _order = 'id'

    name = fields.Char('订单号码', readonly=True, index=True,
                       default='New')
    user_id = fields.Many2one('res.users', string='用户', default=lambda self: self.env.user, copy=False)
    partner_id = fields.Many2one('res.partner', string='客人', required=True, domain=[('customer', '=', True)],
                                 change_default=True, index=True, track_visibility='always', track_sequence=1)
    checkin_date = fields.Date(string='入住时间')
    checkout_date = fields.Date(string='离店时间')
    channel_id = fields.Many2one('channel', string='渠道')
    channel_num = fields.Char(string='渠道订单编号')
    yd_id = fields.Many2one('yd.house', readonly=True, string='预订订单号')
    room_ids = fields.One2many('room.line', 'order_id', u'房间信息', copy=False)
    room_amount = fields.Float('房费合计', store=True, readonly=True,
                        compute='_compute_room_amount',)
    have_meals_ids = fields.One2many('have.meals.line', 'order_id', u'用餐信息', copy=False)
    house_activity_ids = fields.One2many('house.activity.line', 'order_id', u'活动信息', copy=False)
    house_cost_ids = fields.One2many('house.cost.line', 'order_id', u'费用信息', copy=False)
    have_meals_amount = fields.Float('餐费合计', store=True, readonly=True,
                               compute='_compute_have_meals_amount', )
    house_activity_amount = fields.Float('活动合计', store=True, readonly=True,
                               compute='_compute_house_activity_amount', )
    house_income_total = fields.Float('收入合计', store=True, readonly=True,
                               compute='_compute_house_income_amount', )
    house_cost_amount = fields.Float('费用合计', store=True, readonly=True,
                               compute='_compute_house_cost_amount', )
    bank_ids = fields.One2many('account.payment', 'private_house_id', u'银行信息', copy=False)
    pay_amount = fields.Float('已付款合计', store=True, readonly=True,
                               compute='_compute_pay_amount', )
    lose = fields.Float('差异', store=True, readonly=True,
                               compute='_compute_house_income_amount', )
    state = fields.Selection([('draft', '草稿'), ('chick_in', '入住'), ('chick_out', '退房'), ('done', '结帐完成'),
                              ('cancel', '取消')], string='状态', readonly=True, default='draft')

    @api.multi
    def order_cancel(self):
        self.state = 'cancel'
        self.partner_id.room_name = ''
        for i in self.room_ids:
            old = self.env['room.date'].search([('date', '=', i.date), ('room_id', '=', i.name.id)])
            old.unlink()

    @api.multi
    def order_confirm(self):
        amount = 0
        for i in self.room_ids:
            old = self.env['room.date'].search([('date', '=', i.date), ('room_id', '=', i.name.id)])
            self.env['house.report'].create({
                'name': i.name.id,
                'date': i.date,
                'user_id': self.user_id.id,
                'partner_id': self.partner_id.id,
                'sale_id': self.id,
                'channel_id': self.channel_id.id,
                'amount': i.amount,
                'channel_amount': i.amount - i.pyamount,
            })
            old.unlink()
            if i.is_channel_pay:
                amount += i.amount
        for i in self.have_meals_ids:
            self.env['consumption.report'].create({
                'name': i.name.id,
                'date': i.date,
                'user_id': self.user_id.id,
                'partner_id': self.partner_id.id,
                'sale_id': self.id,
                'channel_id': self.channel_id.id,
                'amount': i.amount,
                'channel_amount': i.amount - i.pyamount,
                'product_type': i.product_type.id,
                'type': i.type.id
            })
            if i.is_channel_pay:
                amount += i.amount
        for i in self.house_activity_ids:
            self.env['consumption.report'].create({
                'name': i.name.id,
                'date': i.date,
                'user_id': self.user_id.id,
                'partner_id': self.partner_id.id,
                'sale_id': self.id,
                'channel_id': self.channel_id.id,
                'amount': i.amount,
                'channel_amount': i.amount - i.pyamount,
                'product_type': i.product_type.id,
                'type':i.type.id
            })
            if i.is_channel_pay:
                amount += i.amount
        self.env['channel.order'].create({
            'name': self.name,
            'partner_id': self.partner_id.id,
            'channel_id': self.channel_id.id,
            'channel_num': self.channel_num,
            'amount': amount,
            'checkin_date': self.checkin_date,
            'checkout_date': self.checkout_date,
        })
        self.state = 'chick_out'
        self.partner_id.room_name = ''

    @api.multi
    def order_chick_in(self):
        self.state = 'chick_in'
        name = ''
        for i in self.room_ids:
            old = self.env['room.date'].search([('date', '=', i.date), ('room_id', '=', i.name.id)])
            if old:
                old.write({
                    'sale_id': self.id,
                    'partner_id': self.partner_id.id,
                    'channel_id': self.channel_id.id,
                    'state': 'done'
                })
            else:
                raise UserError("房间未预约!")
            if name:
                name = name + "," + i.name.name
            else:
                name = i.name.name
        self.partner_id.room_name = name

    @api.multi
    @api.depends('bank_ids')
    def _compute_pay_amount(self):
        amount = 0
        for line in self.bank_ids:
            if line.partner_type == 'customer':
                if line.payment_type == 'inbound':
                    amount += line.amount
                if line.payment_type == 'outbound':
                    amount = amount - line.amount
        self.pay_amount = amount

    @api.multi
    @api.depends('room_amount', 'have_meals_amount', 'house_activity_amount','pay_amount')
    def _compute_house_income_amount(self):
        '''
        收入合计
        '''
        self.house_income_total = self.room_amount + self.have_meals_amount + self.house_activity_amount
        self.lose = self.house_income_total - self.pay_amount

    @api.multi
    @api.depends('room_ids.pyamount')
    def _compute_room_amount(self):
        '''
        合计房费
        '''
        total = 0
        for line in self.room_ids:
            total = total + line.pyamount
        self.room_amount = total

    @api.multi
    @api.depends('have_meals_ids.pyamount')
    def _compute_have_meals_amount(self):
        '''
        合计餐费
        '''
        total = 0
        for line in self.have_meals_ids:
            total = total + line.pyamount
        self.have_meals_amount = total

    @api.multi
    @api.depends('house_activity_ids.pyamount')
    def _compute_house_activity_amount(self):
        '''
        合计活动费
        '''
        total = 0
        for line in self.house_activity_ids:
            total = total + line.pyamount
        self.house_activity_amount = total

    @api.multi
    @api.depends('house_cost_ids.amount')
    def _compute_house_cost_amount(self):
        '''
        合计支出
        '''
        total = 0
        for line in self.house_cost_ids:
            total = total + line.amount
        self.house_cost_amount = total

class RoomDate(models.Model):
    _name = 'room.date'
    _description = 'Room Date'
    _order = 'date'

    '''
    重要模块,房间预订计算
    '''
    room_id = fields.Many2one('house.room', string='房间信息', required=True, ondelete='cascade', index=True, copy=False,
                               readonly=True)
    date = fields.Date(string='日期', required=True)
    name = fields.Char("房间名")
    user_id = fields.Many2one('res.users', '操作人')
    partner_id = fields.Many2one('res.partner', string='客人', domain=[('customer', '=', True)],
                                 change_default=True, index=True, track_visibility='always', track_sequence=1)
    state = fields.Selection([('confirm', '预订'), ('done', '入住'), ('maintain', '维护')],
                             string='状态', readonly=True, default='draft')
    yd_id = fields.Many2one('yd.house', string='预订信息', copy=False, readonly=True)
    sale_id = fields.Many2one('house.order', string='订单信息', copy=False, readonly=True)
    channel_id = fields.Many2one('channel', string='渠道',)

    _sql_constraints = [
        ('channel_date_room_id', 'unique (date,room_id)', '同一天房间不能重复开')
    ]

class RoomLine(models.Model):
    _name = 'room.line'
    _description = 'Room Line'

    name = fields.Many2one('house.room', required=True, string='房间号')
    order_id = fields.Many2one('house.order', string='订房信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    date = fields.Date(string='入住时间', required=True, default=lambda self: fields.Date.today())
    is_channel_pay = fields.Boolean(string='平台支付')
    amount = fields.Float(string='金额')
    can_use_room = fields.Char(string='可用房')
    pyamount = fields.Float(string='需付金额',store=True,readonly=True,
                               compute='_compute_pyamount',)

    @api.model
    def write(self, vals):
        self.ensure_one()
        if vals.get('name') or vals.get('date'):
            old = self.env['room.date'].search([('date', '=', self.date), ('room_id', '=', self.name.id)])
            old.write({'room_id': vals.get('name') or self.name.id,
                       'date': vals.get('name') or self.name.id})
        ret_val = super(RoomLine, self).write(vals)
        return ret_val

    @api.model
    def create(self, vals):
        if vals.get('is_yd'):
            return super(RoomLine, self).create(vals)
        ret_val = super(RoomLine, self).create(vals)
        order_id = self.env['house.order'].search([('id', '=', vals.get('order_id'))])
        room_id = vals.get('name')
        room_name = self.env['house.room'].search([('id', '=', room_id)])

        self.env['room.date'].create({
            'name': room_name.name,
            'date': vals.get('date'),
            'partner_id': order_id.partner_id.id,
            'state': 'confirm',
            'room_id': room_id,
            'channel_id': order_id.channel_id.id,
            'yd_id': order_id.yd_id.id,
        })
        return ret_val

    @api.multi
    def unlink(self):
        old = self.env['room.date'].search([('room_id', '=', self.name.id), ('date', '=', self.date)])
        old.unlink()
        return super(RoomLine, self).unlink()

    @api.multi
    @api.depends('is_channel_pay', 'amount')
    def _compute_pyamount(self):
        self.ensure_one()
        if self.is_channel_pay:
            self.pyamount = 0
        else:
            self.pyamount = self.amount

    @api.onchange('number', 'price')
    def _compute_amount(self):
        self.ensure_one()
        self.amount = self.number * self.price

class HaveMealsLine(models.Model):
    _name = 'have.meals.line'
    _description = 'Have Meals Line'

    name = fields.Many2one('product.product', string='用餐商品')
    date = fields.Date(string='订单日期', index=True, default=lambda self: fields.Date.today())
    order_id = fields.Many2one('house.order', string='订房信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    amount = fields.Float(string='金额')
    is_channel_pay = fields.Boolean(string='平台支付')
    pyamount = fields.Float(string='需付金额', store=True, readonly=True,
                            compute='_compute_pyamount', )
    product_type = fields.Many2one('product.category', string='产品分类')
    type = fields.Many2one('house.type', string='分类', domain=[('is_room', '=', False)])

    @api.onchange('name')
    def get_amount(self):
        self.product_type = self.name.categ_id

    @api.multi
    @api.depends('is_channel_pay', 'amount')
    def _compute_pyamount(self):
        if self.is_channel_pay:
            self.pyamount = 0
        else:
            self.pyamount = self.amount

class HouseActivityLine(models.Model):
    _name = 'house.activity.line'
    _description = 'House Activity Line'

    name = fields.Many2one('product.product', string='活动商品')
    date = fields.Date(string='订单日期', index=True, default=lambda self: fields.Date.today())
    order_id = fields.Many2one('house.order', string='订房信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    amount = fields.Float(string='金额')
    is_channel_pay = fields.Boolean(string='平台支付')
    pyamount = fields.Float(string='需付金额', store=True, readonly=True,
                            compute='_compute_pyamount', )
    product_type = fields.Many2one('product.category', string='产品分类')
    type = fields.Many2one('house.type', string='分类', domain=[('is_room', '=', False)])

    @api.onchange('name')
    def get_amount(self):
        self.product_type = self.name.categ_id

    @api.multi
    @api.depends('is_channel_pay', 'amount')
    def _compute_pyamount(self):
        if self.is_channel_pay:
            self.pyamount = 0
        else:
            self.pyamount = self.amount

class HouseCostLine(models.Model):
    _name = 'house.cost.line'
    _description = 'House Cost Line'

    name = fields.Many2one('product.product', string='支出商品')
    date = fields.Date(string='订单日期', index=True, default=lambda self: fields.Date.today())
    order_id = fields.Many2one('house.order', string='订房信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    amount = fields.Float(string='金额')
    product_type = fields.Many2one('product.category', string='产品分类')

    @api.onchange('name')
    def get_amount(self):
        self.product_type = self.name.categ_id

class Channel(models.Model):
    _name = 'channel'
    _description = 'Sale channel'
    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']

    name = fields.Many2one('res.partner', string='渠道商', required=True, domain=[('supplier', '=', True)])
    begin_date = fields.Date(string='签约日期', default=lambda self: fields.Date.today())
    end_date = fields.Date(string='到期日期')
    discount_rate = fields.Float(string='折扣率')
    note = fields.Text(string='条款')
    is_channel_pay = fields.Boolean(string='平台支付')
    url = fields.Char('网址')
    account_id = fields.Char('用户名')
    password = fields.Char('密码')


    @api.multi
    @api.returns('mail.message', lambda value: value.id)
    def message_post(self, **kwargs):
        return super(Channel, self.with_context(mail_post_autofollow=True)).message_post(**kwargs)

    @api.multi
    def write(self, vals):
        self.ensure_one()
        send_massage = ''
        if len(vals):
            if vals.get('name'):
                send_massage = '渠道商名称由(%s)改为(%s)'%(vals['name'], self.name) + '\n'
            if vals.get('note'):
                send_massage = send_massage + '内容由%s改为%s '%(vals['note'], self.note) + '\n'
            if vals.get('begin_date'):
                send_massage = send_massage + '开始日期由%s改为%s ' % (vals['note'], self.note) + '\n'
            if vals.get('end_date'):
                send_massage = send_massage + '到期日期由%s改为%s ' % (vals['note'], self.note) + '\n'
        self.message_post(send_massage)
        ret_val = super(Channel, self).write(vals)
        return ret_val

class account_payment(models.Model):
    _inherit = "account.payment"

    private_house_id = fields.Many2one('house.order', string='订房信息', ondelete='cascade', index=True, copy=False,
                               readonly=True)

class Company(models.Model):
    _inherit = "res.company"

    erweima = fields.Binary(string="erweima")

class YdHouseIn(models.Model):
    _name = 'yd.house.in'
    _description = 'yd house income'

    name = fields.Many2one('product.product', string='收入商品/服务')
    date = fields.Date(string='订单日期', index=True, default=lambda self: fields.Date.today())
    order_id = fields.Many2one('yd.house', string='预订信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    amount = fields.Float(string='金额')

class YdHouseOut(models.Model):
    _name = 'yd.house.out'
    _description = 'yd house pay'

    name = fields.Many2one('product.product', string='支出商品/服务')
    date = fields.Date(string='订单日期', index=True, default=lambda self: fields.Date.today())
    order_id = fields.Many2one('yd.house', string='预订信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    amount = fields.Float(string='金额')

class YdHouseRoom(models.Model):
    _name = 'yd.house.room'
    _description = 'yd house room'

    name = fields.Many2one('house.room', required=True, string='房间号')
    order_id = fields.Many2one('yd.house', string='预订信息', required=True, ondelete='cascade', index=True, copy=False, readonly=True)
    date = fields.Date(string='入住时间', required=True, default=lambda self: fields.Date.today())
    amount = fields.Float(string='金额')

class YdHouse(models.Model):
    _name = 'yd.house'
    _description = 'Yd House'
    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
    _order = 'checkin_date desc'

    name = fields.Datetime('订单号码', readonly=True, index=True,
                       default=(lambda *a: time.strftime(dt)))
    partner_id = fields.Many2one('res.partner', string='客人', required=True, domain=[('customer', '=', True)],
                                 change_default=True, index=True, track_visibility='always', track_sequence=1,
                                 states={'draft': [('readonly', False)]},)
    channel_id = fields.Many2one('channel', string='渠道', states={'draft': [('readonly', False)]},)
    channel_num = fields.Char(string='渠道订单编号')
    room_num = fields.Integer('需房间数', default=1, states={'draft': [('readonly', False)]})
    checkin_date = fields.Date(string='入住时间', required=True, default=lambda self: fields.Date.today(),
                               states={'draft': [('readonly', False)]},)
    checkout_date = fields.Date(string='离店时间', required=True, states={'draft': [('readonly', False)]},)
    room_ids = fields.Many2many('house.room', string='房间号码', states={'draft': [('readonly', False)]},)
    line_ids = fields.One2many('yd.house.line', 'order_id', u'套餐内容', copy=False, states={'draft': [('readonly', False)]},)
    is_team = fields.Boolean(string='团队高级模式', states={'draft': [('readonly', False)]},)
    line_rooms = fields.One2many('yd.house.room', 'order_id', u'自定义住房', copy=False, states={'draft': [('readonly', False)]},)
    line_ins = fields.One2many('yd.house.in', 'order_id', u'自定义进项', copy=False,
                                 states={'draft': [('readonly', False)]}, )
    line_outs = fields.One2many('yd.house.out', 'order_id', u'自定义出支项', copy=False,
                               states={'draft': [('readonly', False)]}, )
    room_dates = fields.One2many('room.date', 'yd_id', u'房间信息', copy=False, readonly=True)
    user_id = fields.Many2one('res.users', string='用户', default=lambda self: self.env.user, copy=False)
    state = fields.Selection([('draft', '草稿'), ('confirm', '确认'), ('done', '完成'),
                              ('cancel', '取消')],
                             string='状态', readonly=True, default='draft')
    sale_id = fields.Many2one('house.order', string='订单管理')

    @api.multi
    def action_view_house_order(self):
        action = self.env.ref('private_house.house_order_action').read()[0]
        action['views'] = [(self.env.ref('private_house.view_house_order_form').id, 'form')]
        action['res_id'] = self.sale_id.id
        return action

    @api.multi
    def write(self, vals):
        #判断退房日期大于入住日期
        if self.checkout_date <= self.checkin_date:
            raise UserError("预订日期有误,请检查!")
        ret_val = super(YdHouse, self).write(vals)
        return ret_val

    @api.multi
    def order_draft(self):
        for i in self.room_dates:
            i.unlink()
        self.state = 'draft'

    @api.multi
    def team_rooms(self):
        dates = []
        begin_date = self.checkin_date
        while begin_date < self.checkout_date:
            date_str = begin_date.strftime("%Y-%m-%d")
            dates.append(date_str)
            begin_date += timedelta(days=1)
        for date in dates:
            for i in self.room_ids:
                self.env['yd.house.room'].create({
                    'name': i.id,
                    'order_id': self.id,
                    'date': date,
                    'amount': i.room_amount
                })

    @api.multi
    def team_confirm(self):
        self.state = 'confirm'
        for i in self.line_rooms:
            self.env['room.date'].create({
                'name': i.name.name,
                'date': i.date,
                'partner_id': self.partner_id.id,
                'state': 'confirm',
                'room_id': i.name.id,
                'channel_id': self.channel_id.id,
                'yd_id': self.id,
            })

    @api.multi
    def yd_to_house_order(self):
        if self.channel_id:
            is_channel_pay = self.channel_id.is_channel_pay
        else:
            is_channel_pay = False
        order_id = self.env['house.order'].create({
            'name': str(self.name) + self.partner_id.name,
            'yd_id': self.id,
            'checkin_date': self.checkin_date,
            'checkout_date': self.checkout_date,
            'partner_id': self.partner_id.id,
            'state': 'draft',
            'channel_id': self.channel_id.id,
            'user_id': self.user_id.id,
        })
        for i in self.line_rooms:
            self.env['room.line'].create({
                'name': i.name.id,
                'order_id': order_id.id,
                'date': i.date,
                'amount': i.amount,
                'is_yd': True,
                'is_channel_pay': is_channel_pay,
            })
        for j in self.line_ins:
            self.env['have.meals.line'].create({
                'name': j.name.id,
                'order_id': order_id.id,
                'date': self.checkin_date,
                'amount': j.amount,
                'is_channel_pay': is_channel_pay,
            })
        for k in self.line_outs:
            self.env['house.cost.line'].create({
                'name': k.name.id,
                'order_id': order_id.id,
                'date': self.checkin_date,
                'amount': k.amount,
                'is_channel_pay': is_channel_pay,
            })
        self.sale_id = order_id.id
        self.state = 'done'

    @api.multi
    def order_confirm(self):
        if self.line_rooms:
            raise UserError('已经计算过,请删除计算内容再试!')

        # 计算日期区间
        dates = []
        begin_date = self.checkin_date
        while begin_date < self.checkout_date:
            date_str = begin_date.strftime("%Y-%m-%d")
            dates.append(date_str)
            begin_date += timedelta(days=1)
        # 计算入住至退房所需总房数
        oder_dates = (self.checkout_date - self.checkin_date).days * self.room_num

        room_dates = 0  #套餐中总房数
        all_amount = 0
        ins_amount = 0
        for i in self.line_ids:
            package = i.name
            if package:
                all_amount += i.amount
                room_dates += package.dates
                #建其他收入项
                for m in package.in_ids:
                    ins_amount += m.amount
                    self.env['yd.house.in'].create({
                        'name': m.name.id,
                        'order_id': self.id,
                        'date': self.checkin_date,
                        'amount': m.amount,
                    })
                # 建其他支出项
                for n in package.out_ids:
                    self.env['yd.house.out'].create({
                        'name': n.name.id,
                        'order_id': self.id,
                        'date': self.checkin_date,
                        'amount': n.amount,
                    })

        room_amount = (all_amount - ins_amount)/room_dates
        if oder_dates != room_dates:
            raise UserError("预订日期数与房间日期数不一致")
        for date in dates:
            if package.all_rooms:
                room_ids = self.env['house.room'].search([])
                used_rooms = self.env['room.date'].search([('date', '=', date)])
            else:
                room_ids = self.env['house.room'].search([('categ_id', '=', package.house_type.id)])
                used_rooms = self.env['room.date'].search(
                    [('room_id', 'in', room_ids.ids), ('date', '=', date)])
            if len(room_ids) - len(used_rooms) < self.room_num:
                raise UserError("%s用房间不足" % (date))
            k = 0
            for room in room_ids.ids:
                if k < self.room_num and room not in used_rooms.ids:
                    self.env['yd.house.room'].create({
                        'name': room,
                        'order_id': self.id,
                        'date': date,
                        'amount': room_amount,
                    })
                    k += 1

class YdHouseLine(models.Model):
    _name = 'yd.house.line'
    _description = 'Yd House Line'

    order_id = fields.Many2one('yd.house', string='预订单', required=True, ondelete='cascade', index=True,
                               copy=False, readonly=True)
    name = fields.Many2one('house.package', u'套餐信息', copy=False)
    date = fields.Date(string='订单日期', index=True, default=lambda self: fields.Date.today())
    have_meals_num = fields.Integer(u'用餐人数', copy=False)
    house_activity_num = fields.Integer(u'活动人数', copy=False)
    amount = fields.Float(string='套餐金额')

    @api.onchange('name')
    def get_amount(self):
        self.amount = self.name.amount

class HousePackage(models.Model):
    _name = 'house.package'
    _description = 'House Package'

    name = fields.Char('套餐名称')
    house_type = fields.Many2one('house.type', string='房型')
    in_ids = fields.One2many('house.package.in', 'order_id', u'套餐收入内容', copy=False,)
    out_ids = fields.One2many('house.package.out', 'order_id', u'套餐支出内容', copy=False,)
    dates = fields.Integer("入住天数")
    amount = fields.Float(string='套餐金额', required=True)
    all_rooms = fields.Boolean(string='所有房间')
    note = fields.Text()

class HousePackageIN(models.Model):
    _name = 'house.package.in'
    _description = 'House Package In'

    name = fields.Many2one('product.product', string='用餐商品')
    order_id = fields.Many2one('house.package', string='套餐名称', required=True, ondelete='cascade', index=True, copy=False,
                               readonly=True)
    amount = fields.Float(string='金额')

class HousePackageOut(models.Model):
    _name = 'house.package.out'
    _description = 'House Package Out'

    name = fields.Many2one('product.product', string='费用商品')
    order_id = fields.Many2one('house.package', string='套餐名称', required=True, ondelete='cascade', index=True, copy=False,
                               readonly=True)
    amount = fields.Float(string='金额')

class HouseReservationSummary(models.Model):

    _name = 'house.reservation.summary'
    _description = '房间预订报表'

    name = fields.Char('Reservation Summary', default='Reservations Summary',
                       invisible=True)
    begin_date = fields.Date('结束日期')
    end_date = fields.Date('开始日期')
    summary_header = fields.Text('Summary Header')
    house_summary = fields.Text('House Summary')

    @api.model
    def default_get(self, vlas):
        res = super(HouseReservationSummary, self).default_get(vlas)
        # Added default datetime as today and date to as today + 30.
        begin_date = datetime.today()
        end_date = begin_date + timedelta(days=30)
        res.update({'begin_date': begin_date, 'end_date': end_date})
        return res

    @api.onchange('begin_date', 'end_date')
    def get_room_summary(self):
        res = {}
        all_detail = []
        room_obj = self.env['house.room']
        user_obj = self.env['res.users']
        date_range_list = []
        main_header = []
        summary_header_list = ['房间']
        begin_date = self.begin_date
        end_date = self.end_date
        if begin_date and end_date:
            if begin_date > end_date:
                raise UserError("开始日期大于结束日期!")
            dates = []
            temp_date = begin_date
            while (temp_date <= end_date):
                date_str = temp_date.strftime("%Y-%m-%d")
                dates.append(date_str)
                val = ''
                val = (str(temp_date.strftime("%a")) + ' ' +
                       str(temp_date.strftime("%b")) + ' ' +
                       str(temp_date.strftime("%d")))
                summary_header_list.append(val)
                date_range_list.append(temp_date.strftime
                                       (dt))
                temp_date = temp_date + timedelta(days=1)
            all_detail.append(summary_header_list)
            room_ids = room_obj.search([])
            main_header.append({'header': summary_header_list})
            self.summary_header = str(main_header)

            all_room_detail = []

            for room in room_ids:
                room_detail = {}
                room_list_stats = []
                room_detail.update({'name': room.name or ''})
                for date in dates:
                    room_used = self.env['room.date'].search([('room_id', '=', room.id), ('date', '=', date)])
                    if room_used and room_used.state == 'confirm':
                        room_list_stats.append({'state': '%s已预订'%(room_used.partner_id.name),
                                                'date': date,
                                                'room_id': room.id,
                                                'house_type': 'confirm',
                                                'data_model': '',
                                                'rom_num': room.name,
                                                'yd_id': room_used[0].yd_id.id,
                                                'yd_model': 'yd.house',
                                                'order_model': 'house.order',
                                                'sale_id': room_used[0].sale_id.id
                                                })
                    elif room_used and room_used.state == 'done':
                        room_list_stats.append({'state': '%s已入住' % (room_used.partner_id.name),
                                                'date': date,
                                                'room_id': room.id,
                                                'house_type': 'done',
                                                'data_model': '',
                                                'rom_num': room.name,
                                                'yd_id': room_used[0].yd_id.id,
                                                'yd_model': 'yd.house',
                                                'order_model': 'house.order',
                                                'sale_id': room_used[0].sale_id.id
                                                })
                    elif room_used and room_used.state == 'maintain':
                        room_list_stats.append({'state': '此房间在维护',
                                                'date': date,
                                                'room_id': room.id,
                                                'house_type': 'maintain'
                                                })
                    else:
                        room_list_stats.append({'state': '空闲',
                                                'date': date,
                                                'room_id': room.id})
                    room_detail.update({'value': room_list_stats})
                all_room_detail.append(room_detail)
            self.house_summary = str(all_room_detail)

class QuickHouseReservation(models.TransientModel):
    _name = 'quick.house.reservation'
    _description = 'Quick House Reservation'

    partner_id = fields.Many2one('res.partner', string="客人", domain=[('customer', '=', True)],
                                 required=True)
    check_in = fields.Date('入住时间', required=True)
    check_out = fields.Date('离店时间', required=True)
    room_ids = fields.Many2many('house.room', string='房间', required=True)
    channel_id = fields.Many2one('channel', string='渠道')
    package_id = fields.Many2one('house.package', u'套餐信息')
    package_num = fields.Integer(string='套餐数量')

    @api.multi
    def house_reserve(self):
        view_id = self.env.ref('private_house.view_yd_house_form').id
        if self.check_out <= self.check_in:
            raise UserError("预订日期有误,请检查!")
        if not self.package_id:
            order = self.env['yd.house'].create({
                'partner_id': self.partner_id.id,
                'checkin_date': self.check_in,
                'checkout_date': self.check_out,
                'channel_id': self.channel_id.id,
                'is_team': True,
                'room_ids': [(6, 0, self.room_ids.ids)],
                'state': 'draft',
            })
            order.team_rooms()
        else:
            if self.package_num == 0:
                raise UserError('套餐数量不能为0')
            room_num = self.package_num * self.package_id.dates / (self.check_out - self.check_in).days
            if room_num != len(self.room_ids):
                raise UserError('套餐数量不等于 日期 * 房间数!')
            order = self.env['yd.house'].create({
                'partner_id': self.partner_id.id,
                'checkin_date': self.check_in,
                'checkout_date': self.check_out,
                'channel_id': self.channel_id.id,
                'is_team': False,
                'room_num': room_num,
                'state': 'draft',
            })
            i = 0
            while i < self.package_num:
                self.env['yd.house.line'].create({
                    'order_id': order.id,
                    'name': self.package_id.id,
                    'amount': self.package_id.amount,
                })
                i += 1
            order.order_confirm()
            k = 0
            for line_id in order.line_rooms:
                if k < len(self.room_ids):
                    line_id.write({'name': self.room_ids.ids[k]})
                    k += 1
                else:
                    k = 0
                    line_id.write({'name': self.room_ids.ids[k]})
                    k += 1

        return {
            'name': 'new',
            'view_type': 'form',
            'view_mode': 'kanban,tree,form',
            'view_id': view_id,
            'views': [(view_id, 'form')],
            'res_model': 'yd.house',
            'res_id': order.id,
            'type': 'ir.actions.act_window',
            'domain': [('id', '=', order.id)],
            'target': 'new',
        }

    @api.model
    def default_get(self, fields):
        if self._context is None:
            self._context = {}
        res = super(QuickHouseReservation, self).default_get(fields)
        if self._context:
            keys = self._context.keys()
            if 'date' in keys:
                res.update({'check_in': self._context['date'],
                            'check_out': str(datetime.strptime(self._context['date'], "%Y-%m-%d")+timedelta(days=1)),})
            if 'house_id' in keys:
                houseid = self._context['house_id']
                res.update({'room_ids': int(houseid)})
        return res

class ChannelOrder(models.Model):
    _name = 'channel.order'
    _description = 'Channel Order'
    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
    _order = 'checkin_date desc'

    name = fields.Char('订单号码', readonly=True, index=True)
    partner_id = fields.Many2one('res.partner', string='客人', required=True, readonly=True,)
    channel_id = fields.Many2one('channel', string='渠道')
    channel_num = fields.Char(string='渠道订单编号')
    amount = fields.Float(string='金额')
    checkin_date = fields.Date(string='入住时间', required=True,)
    checkout_date = fields.Date(string='离店时间', required=True,)

class ResPartner(models.Model):
    _inherit = 'res.partner'

    room_name = fields.Char(string='房间号')

class HouseReport(models.Model):
    _name = 'house.report'
    _description = 'House Report'

    name = fields.Many2one('house.room', string='房间信息', required=True, ondelete='cascade', index=True, copy=False,
                              readonly=True)
    date = fields.Date(string='日期', required=True)
    user_id = fields.Many2one('res.users', '操作人')
    partner_id = fields.Many2one('res.partner', string='客人', required=True, domain=[('customer', '=', True)],
                                 change_default=True, index=True, track_visibility='always', track_sequence=1)
    sale_id = fields.Many2one('house.order', string='订单信息', ondelete='cascade', index=True, copy=False,
                              readonly=True)
    channel_id = fields.Many2one('channel', string='渠道')
    amount = fields.Float(string='金额')
    channel_amount = fields.Float(string='渠道支付金额')

class ConsumptionReport(models.Model):
    _name = 'consumption.report'
    _description = 'Consumption Report'

    name = fields.Many2one('product.product', string='商品')
    date = fields.Date(string='日期', required=True)
    user_id = fields.Many2one('res.users', '操作人')
    partner_id = fields.Many2one('res.partner', string='客人', required=True, domain=[('customer', '=', True)],
                                 change_default=True, index=True, track_visibility='always', track_sequence=1)
    sale_id = fields.Many2one('house.order', string='订单信息', ondelete='cascade', index=True, copy=False,
                              readonly=True)
    channel_id = fields.Many2one('channel', string='渠道')
    amount = fields.Float(string='金额')
    channel_amount = fields.Float(string='渠道支付金额')
    product_type = fields.Many2one('product.category', string='产品分类')
    type = fields.Many2one('house.type', string='分类', domain=[('is_room', '=', False)])

class HouseMaintain(models.Model):
    _name = 'house.maintain'
    _description = 'House Maintain'

    name = fields.Many2one('house.room', string='房间信息', required=True, ondelete='cascade', index=True, copy=False,
                           readonly=True)
    begin_date = fields.Date(string='开始日期', required=True)
    end_date = fields.Date(string='结束日期', required=True)
    state = fields.Selection([('draft', '草稿'), ('confirm', '确认'), ('done', '完成')],
                             string='状态', readonly=True, default='draft')

    @api.multi
    def to_confirm(self):
        # 计算日期区间
        if self.end_date < self.begin_date:
            raise UserError('开始日期不能小于结束日期')
        dates = []
        begin_date = self.begin_date
        while begin_date < self.end_date:
            date_str = begin_date.strftime("%Y-%m-%d")
            dates.append(date_str)
            begin_date += timedelta(days=1)

        for date in dates:
            old = self.env['room.date'].search([('date', '=', date), ('room_id', '=', self.name.id)])
            if old:
                raise UserError("此时间段房间不为空,不能进入维修!")
            else:
                self.env['room.date'].create({
                    'name': self.name.name,
                    'date': date,
                    'state': 'maintain',
                    'room_id': self.name.id,
                })
        self.state = 'confirm'

    @api.multi
    def to_done(self):
        # 计算日期区间
        if self.end_date < self.begin_date:
            raise UserError('开始日期不能小于结束日期')
        dates = []
        begin_date = self.begin_date
        while begin_date < self.end_date:
            date_str = begin_date.strftime("%Y-%m-%d")
            dates.append(date_str)
            begin_date += timedelta(days=1)

        for date in dates:
            old = self.env['room.date'].search([('date', '=', date), ('room_id', '=', self.name.id)])
            if old:
                old.unlink()
            else:
                raise UserError('房间状态不对')
        self.state = 'done'